﻿using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Ude;

namespace DimensionsHelper.Common.Utils;

public static partial class FileHelper
{
    public static Encoding DetectTextEncoding(string text)
    {
        Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
        return UnicodeRegex().IsMatch(text) ? Encoding.GetEncoding("GBK") : Encoding.UTF8;
    }

    public static Encoding DetectFileEncoding(FileStream fileStream)
    {
        Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

        // BOM

        if (fileStream.Length < 3)
        {
            return Encoding.Default;
        }

        byte[] buffer = new byte[4];

        _ = fileStream.Read(buffer, 0, buffer.Length);

        if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf)
        {
            return Encoding.UTF8;
        }

        if (buffer[0] == 0xfe && buffer[1] == 0xff)
        {
            return Encoding.BigEndianUnicode;
        }

        if (buffer[0] == 0xff && buffer[1] == 0xfe)
        {
            return Encoding.Unicode;
        }

        if (buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0xfe && buffer[3] == 0xff)
        {
            return Encoding.UTF32;
        }

        // 无BOM      
        fileStream.Seek(0, SeekOrigin.Begin);
        byte[] bytes = new byte[fileStream.Length];
        fileStream.Read(bytes, 0, bytes.Length);
        var detector = new CharsetDetector();
        detector.Feed(bytes, 0, bytes.Length);
        detector.DataEnd();

        if (!string.IsNullOrEmpty(detector.Charset))
        {
            // 进一步检查中文编码
            if (detector.Charset.StartsWith("windows-", StringComparison.OrdinalIgnoreCase))
            {
                // 检查中文字符                
                int p = 0;
                while (p < bytes.Length)
                {
                    byte b = bytes[p];
                    // 跳过ASCII
                    if (b < 0x80)
                    {
                        p++;
                        continue;
                    }
                    // GBK双字节编码：第一个字节范围 0x81 到 0xFE，第二个字节范围 0x40 到 0x7E 或 0x80 到 0xFE。
                    // GBK标点首字节范围：0x81-0xFE，次字节：0x40-0xFE（排除0x7F）
                    if (b >= 0x81 && b <= 0xfe && p + 1 < bytes.Length)
                    {
                        p++;
                        byte next = bytes[p];
                        if (next != 0x7f && next >= 0x40 && next <= 0xfe)
                        {
                            return Encoding.GetEncoding("GBK");
                        }
                    }

                    p++;
                }
            }

            return Encoding.GetEncoding(detector.Charset);
        }

        return Encoding.Default;
    }


    public static void DeleteFile(string path)
    {
        if (File.Exists(path))
        {
            File.Delete(path);
        }
    }

    [GeneratedRegex(@"[\u4e00-\u9fa5]")]
    private static partial Regex UnicodeRegex();
}